package com.ll.base.util;


import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * List 工具类
 *
 * @author yinuo
 * @date 2018/12/21
 */
public class ListUtil {
    public static <T, R> List<R> toList(List<T> list, Function<? super T, ? extends R> mapper) {
        return list != null ? list.stream().map(mapper).collect(Collectors.toList()) : Collections.emptyList();
    }

    public static <T, R> List<R> toListAndDistinct(List<T> list, Function<? super T, ? extends R> mapper) {
        return list != null ? list.stream().map(mapper).distinct().collect(Collectors.toList()) : Collections.emptyList();
    }

    public static <T, R> Map<R, T> toMap(List<T> list, Function<? super T, ? extends R> getKeyMapper) {
        return list != null ? list.stream().collect(HashMap::new, (m, v) -> m.put(getKeyMapper.apply(v), v), HashMap::putAll) : Collections.emptyMap();
    }

    public static <T, R, V> Map<R, V> toMap(Collection<T> list, Function<? super T, ? extends R> getKeyMapper, Function<? super T, ? extends V> getValueMapper) {
        return list != null ? list.stream().collect(HashMap::new, (m, v) -> m.put(getKeyMapper.apply(v), getValueMapper.apply(v)), HashMap::putAll) : Collections.emptyMap();
    }

    @SafeVarargs
    public static <T> List<T> flatMap(List<T>... args) {
        return Stream.of(args).flatMap(List<T>::stream).collect(Collectors.toList());
    }

    public static <T> List<T> filter(List<T> list, Predicate<T> predicate) {
        return list != null ? list.stream().filter(predicate).collect(Collectors.toList()) : Collections.emptyList();
    }

    public static <T, R> List<R> fitlerAndToList(List<T> list, Predicate<T> predicate, Function<? super T, ? extends R> mapper) {
        return list != null ? list.stream().filter(predicate).map(mapper).collect(Collectors.toList()) : Collections.emptyList();
    }

    public static <T, R, V> Map<R, V> filterAndToMap(List<T> list, Predicate<T> predicate, Function<? super T, ? extends R> getKeyMapper, Function<? super T, ? extends V> getValueMapper) {
        return list != null ? list.stream().filter(predicate).collect(HashMap::new, (m, v) -> m.put(getKeyMapper.apply(v), getValueMapper.apply(v)), HashMap::putAll) : Collections.emptyMap();
    }

    public static <T> T first(List<T> list) {
        return ScalarUtil.isNotEmpty(list) ? list.get(0) : null;
    }

//    public static <T, R> Map<R, List<T>> group(List<T> list, Function<T, R> mapper) {
//        if(ScalarUtil.isEmpty(list)){
//            return null;
//        }
//        Map<R, List<T>> collect = list.stream().collect(Collectors.groupingBy(mapper));
//        return collect;
//    }
}
